#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "bmock.hpp"
#include "bmock_control_tools_mock.hpp"

static void f(const int* x, int* y, int* z) {
	MOCK_VOID(3, (IN(x), OUT(y), IN_OUT(z)));
}
static void g(const char* x, char* y, char* z) {
	MOCK_VOID(3,(RAW_MEM(IN,x,1),RAW_MEM(OUT,y,1),RAW_MEM(IN_OUT,z,1)));
}
static void h(const char* x, char* y, char* z) {
	MOCK_VOID(3,(IN(x),OUT(y),IN_OUT(z)));
}

struct null_ptr_tester2 {
	null_ptr_tester2() {
		BMOCK_CREATE_MOCK(*);
	}
	~null_ptr_tester2() {
		BMOCK_VERIFY;
	}
};

BMOCK_TEST(null_ptr_tester2,test_regular_OK) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(f(NULL,NULL,NULL)));
	BMOCK_REPLAY;
	f(NULL,NULL,NULL);
}

BOOST_AUTO_TEST_CASE(test_regular_XY_ERROR2) {
	__BMOCK_CONTROL(c);
	const int               x = 10;
	int                     y = 13;
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+10);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,boost::lexical_cast<std::string>(x),bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(true,true,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"y"),loc));
	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::ARG_UPDATE,"y"),loc,false,false));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(f(&x,&y,NULL),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(test_regular_Z_ERROR2) {
	__BMOCK_CONTROL(c);
	int                     z = 53;
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+8);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,bmock::NULL_STR,bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,true,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(f(NULL,NULL,&z),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BMOCK_TEST(null_ptr_tester2,test_raw_mem2) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(g(NULL,NULL,NULL)));
	BMOCK_REPLAY;
	g(NULL,NULL,NULL);
}

BOOST_AUTO_TEST_CASE(test_raw_mem_XY_ERROR2) {
	__BMOCK_CONTROL(c);
	const char              x = 'A';
	char                    y = 'B';
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+9);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,"41",bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(true,true,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"y"),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,g(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(g(&x,&y,NULL),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(test_raw_mem_Z_ERROR2) {
	__BMOCK_CONTROL(c);
	char                    z = 'C';
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+8);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,bmock::NULL_STR,bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,true,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,g(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(g(NULL,NULL,&z),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BMOCK_TEST(null_ptr_tester2,test_string) {
	BOOST_CHECK_NO_THROW(BMOCK_EXPECT(h(NULL,NULL,NULL)));
	BMOCK_REPLAY;
	h(NULL,NULL,NULL);
}

BOOST_AUTO_TEST_CASE(test_string_XY_ERROR2) {
	__BMOCK_CONTROL(c);
	const char             *x = "ABCDEFG";
	char                    y[sizeof(x)];
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+9);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,x,bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,false,t->check_ptr(true,true,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_RETURN_C(c,true,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"y"),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,h(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(h(x,y,NULL),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(test_string_Z_ERROR2) {
	__BMOCK_CONTROL(c);
	char                    z[] = "ABCD";
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+8);

	__BMOCK_EXPECT_RETURN_C(c,false,t->check_equal(bmock::NULL_STR,bmock::NULL_STR,bmock::message(bmock::ARG_VALUE,"x"),loc));
	__BMOCK_EXPECT_RETURN_C(c,true,t->check_ptr(true,false,bmock::message(bmock::ARG_PTR,"z"),loc));
	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->abort(loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,h(NULL,NULL,NULL));
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(h(NULL,NULL,z),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

